import json

from flask_restx import Namespace, Resource, fields
from flask import request, jsonify
import requests  # 导入 requests 库
import os  # 导入 os 库以获取证书的相对路径

import app1

# from config import Config  # 导入配置

# 创建 Flask-RESTx 命名空间
ns_drip = Namespace('ns_drip', description='drip operations')

# 使用 Flask-RESTx 定义模型
drip_model = ns_drip.model(
    'drip',
    {
        "access_token": fields.String(description='令牌'),
        "token_type": fields.String(description='前缀'),
        "expires_in": fields.Integer(description='失效时间'),
        "scope": fields.String(description='profile'),
        "client_id": fields.String(description='用户')
    }
)

# 定义外层的响应模型
response_model = ns_drip.model('Response_detail', {
    'message': fields.Nested(ns_drip.model('Message_detail', {
        "result": fields.Integer(description='查询结果返回值'),
        "result_text": fields.String(description='查询结果信息'),
        'count': fields.Integer(description='查询结果返回数据条数'),
        'data': fields.List(fields.Nested(drip_model))
    }))
})

drip_query_model = ns_drip.model(
    'drip_query',
    {
        "client_id": fields.List(fields.String, description='用户', default=app1.app.config['DEFAULT_CLIENT_ID']),
        "client_secret": fields.List(fields.String, description='客户密钥',
                                     default=app1.app.config['DEFAULT_CLIENT_SECRET']),
        "grant_type": fields.List(fields.String, description='授权类型', default=app1.app.config['DEFAULT_GRANT_TYPE']),
    }
)

# targetType 两种取值 individual group
drip_query_notice_model = ns_drip.model(
    'drip_query_notice',
    {
        "access_token": fields.List(fields.String, description='access_token'),
        "type": fields.List(fields.String, description='类型', default="text"),
        "title": fields.List(fields.String, description='主题', default="Drip_test1"),
        "content": fields.List(fields.String, description='内容', default="Drip_content_test1"),
        "targetType": fields.List(fields.String, description='目标类型', default="individual"),
        "targetId": fields.List(fields.String, description='目标Id', default="test888")
    }
)

drip_notice_model = ns_drip.model(
    'drip_notice',
    {
        "data": fields.Nested(ns_drip.model('data_detail', {
            "id": fields.String(description='返回id')
        })),
        "status": fields.Integer(description='返回码'),
    }
)

# 定义外层的响应模型
response_notice_model = ns_drip.model('Response_notice_detail', {
    'message': fields.Nested(ns_drip.model('Message_detail', {
        "result": fields.Integer(description='查询结果返回值'),
        "result_text": fields.String(description='查询结果信息'),
        'count': fields.Integer(description='查询结果返回数据条数'),
        'data': fields.List(fields.Nested(drip_notice_model))
    }))
})


# # 定义查询资源
# @ns_drip.route('/drip/oidc/oauth/token')
# class Dripoidcoauthtoken(Resource):
#     @ns_drip.expect(drip_query_model)
#     @ns_drip.marshal_with(response_model)
#     def post(self):
#         try:
#             # 获取传入的查询条件
#             data = request.json
#
#             # 拼接 url
#             baseurl = "https://" + (app1.app.config['BASE_DRIP'] + app1.app.config['PATHTOKEN'] + "?client_id=" +
#                                    data["client_id"] + "&client_secret=" +
#                                    data["client_secret"] + "&grant_type=" + data["grant_type"])
#
#             print(baseurl)
#
#             # 访问 baseurl， 如果正常返回，则将返回内容返回给前端
#             # 访问 baseurl
#             # response = requests.post(baseurl)
#
#             # 获取证书的相对路径
#             cert_path = os.path.join(os.path.dirname(__file__), 'drip-ca.pem')
#
#             # 访问 baseurl，加载证书
#             response = requests.post(baseurl, cert=cert_path)
#
#             # 判断响应是否成功
#             if response.status_code == 200:
#                 # 解析响应数据
#                 response_json = response.json()
#
#                 # 准备响应数据
#                 response_data = {
#                     "message": {
#                         "result": 1,  # 查询成功
#                         "result_text": "查询成功",
#                         "count": 1,  # 返回1个记录
#                         "data": [response_json]  # 将响应数据放入 data
#                     }
#                 }
#             else:
#                 # 如果请求未成功，则返回空数据
#                 response_data = {
#                     "message": {
#                         "result": 0,  # 查询异常
#                         "result_text": f"查询失败，状态码: {response.status_code}",
#                         "count": 0,
#                         "data": []
#                     }
#                 }
#
#             # 返回封装好的响应模型
#             return response_data, 200
#
#         except Exception as e:
#             # 捕获异常并准备异常响应数据
#             response_data = {
#                 "message": {
#                     "result": 0,  # 查询异常
#                     "result_text": f"查询异常: {str(e)}",
#                     "count": 0,
#                     "data": []
#                 }
#             }
#             # 返回封装好的异常响应模型，状态码201
#             return response_data, 201

# 定义查询资源
@ns_drip.route('/drip/oidc/oauth/token')
class Dripoidcoauthtoken(Resource):
    @ns_drip.expect(drip_query_model)
    @ns_drip.marshal_with(response_model)
    def post(self):
        """获取水滴令牌"""
        try:
            # 获取传入的查询条件
            data = request.json

            # 拼接 url
            baseurl = "https://" + (app1.app.config['BASE_DRIP'] + app1.app.config['PATHTOKEN'] + "?client_id=" +
                                    data["client_id"] + "&client_secret=" +
                                    data["client_secret"] + "&grant_type=" + data["grant_type"])

            print(baseurl)

            # for dev test  ======================
            if data["client_id"] == "test":
                print("for dev test")

                testdata = {
                    "access_token": "d0ed953d-c1c1-41a1-b239-ca38edd2495d",
                    "token_type": "bearer",
                    "expires_in": 559,
                    "scope": "profile",
                    "client_id": "test"
                }

                response_data = {
                    "message": {
                        "result": 3,  # 查询异常
                        "result_text": f"dev test 正常",
                        "count": 0,
                        "data": testdata
                    }
                }
                # 返回封装好的异常响应模型，状态码201
                return response_data, 202
            # ========================================

            # 获取 CA 证书的相对路径
            ca_cert_path = os.path.join(os.path.dirname(__file__), 'drip-ca.pem')

            # 检查文件是否存在，帮助调试问题
            if not os.path.exists(ca_cert_path):
                print(f"CA证书文件不存在: {ca_cert_path}")
                return {"message": {"result": 0, "result_text": "CA证书文件不存在", "count": 0, "data": []}}, 400

            # 使用
            # verify
            # 参数验证服务器证书是否正确，而非客户端认证。如果是双向认证，使用
            # cert
            # 参数加载客户端证书。
            # 访问 baseurl，并验证服务器证书
            response = requests.post(baseurl, verify=ca_cert_path)

            # 判断响应是否成功
            if response.status_code == 200:
                # 解析响应数据
                response_json = response.json()

                # 准备响应数据
                response_data = {
                    "message": {
                        "result": 1,  # 查询成功
                        "result_text": "查询成功",
                        "count": 1,  # 返回1个记录
                        "data": [response_json]  # 将响应数据放入 data
                    }
                }
            else:
                # 如果请求未成功，则返回空数据
                response_data = {
                    "message": {
                        "result": 0,  # 查询异常
                        "result_text": f"查询失败，状态码: {response.status_code}",
                        "count": 0,
                        "data": []
                    }
                }

            # 返回封装好的响应模型
            return response_data, 200

        except requests.exceptions.SSLError as ssl_err:
            # 捕获SSL错误并返回有用信息
            print(f"SSL错误: {ssl_err}")
            return {"message": {"result": 0, "result_text": f"SSL错误: {ssl_err}", "count": 0, "data": []}}, 500

        except Exception as e:
            # 捕获其他异常并准备异常响应数据
            print(f"其他错误: {e}")
            response_data = {
                "message": {
                    "result": 0,  # 查询异常
                    "result_text": f"查询异常: {str(e)}",
                    "count": 0,
                    "data": []
                }
            }
            # 返回封装好的异常响应模型，状态码201
            return response_data, 201


@ns_drip.route('/drip/api/iins/notification/notice')
class Dripapiiinsnotice(Resource):
    @ns_drip.expect(drip_query_notice_model)
    @ns_drip.marshal_with(response_notice_model)
    def post(self):
        """输入水滴令牌和发送者id发送消息"""
        try:
            # 获取传入的查询条件
            data = request.json

            # 拼接 url
            baseurl = "http://" + (app1.app.config['BASE_DRIP'] + app1.app.config['PATHNOTICE'])

            # 构造请求头
            access_token = data["access_token"][0]  # 从传入数据中获取 access_token
            headers = {
                "Authorization": f"Bearer {access_token}",
                "Content-Type": "application/json"
            }

            # 构造请求体
            # 输入预设是数组，但是取值不需要加 [0]
            request_body = {
                "type": data["type"],  # 选择第一个 type
                "title": data["title"],  # 选择第一个 title
                "content": data["content"],  # 选择第一个 content
                "targets": [
                    {
                        "targetType": data["targetType"],  # 选择第一个 targetType
                        "targetId": data["targetId"]  # 选择第一个 targetId
                    }
                ]
            }

            # for dev test
            print("debug1")
            if data["targetId"] == "test888":
                retdata = {
                    "data": {
                        "id": "963aa0aa90c4c3190191b1bf0499101b"
                    },
                    "status": 202
                }
                response_data = {
                    "message": {
                        "result": 3,  # 查询异常
                        "result_text": "test8888 测试成功",
                        "count": 0,
                        "data": retdata
                    }
                }
                # 返回封装好的异常响应模型，状态码201
                return response_data, 202

            # 发送 POST 请求
            response = requests.post(baseurl, headers=headers, data=json.dumps(request_body))

            # 判断响应是否成功
            if response.status_code == 200:
                response_json = response.json()

                # 准备响应数据
                response_data = {
                    "message": {
                        "result": 1,  # 查询成功
                        "result_text": "发送成功",
                        "count": 1,  # 返回一条记录
                        "data": [
                            {
                                "data": {
                                    "id": response_json["data"]["id"]  # 返回的通知 ID
                                },
                                "status": response_json["status"]
                            }
                        ]
                    }
                }
            else:
                # 如果请求失败，返回错误信息
                response_data = {
                    "message": {
                        "result": 0,  # 查询失败
                        "result_text": f"发送失败，状态码: {response.status_code}",
                        "count": 0,
                        "data": []
                    }
                }

            # 返回封装好的响应模型
            return response_data, 200

        except Exception as e:
            # 捕获其他异常并准备异常响应数据
            print(f"其他错误: {e}")
            response_data = {
                "message": {
                    "result": 0,  # 查询异常
                    "result_text": f"发送异常: {str(e)}",
                    "count": 0,
                    "data": []
                }
            }
            # 返回封装好的异常响应模型，状态码201
            return response_data, 201
